import os
import sys
import traceback
import shutil
import zipfile


# 删除文件
def remove_file(path):
    if os.path.isfile(path) or os.path.islink(path):
        os.remove(path)

# 删除文件夹
def remove_folder(path):
    if os.path.exists(path):
        if os.path.isfile(path) or os.path.islink(path):
            os.remove(path)
        else:
            for filename in os.listdir(path):
                remove_folder(os.path.join(path, filename))
            os.rmdir(path)

# 复制文件
def copy_file(src,dst):
    if os.path.exists(src):
        parent_dir = os.path.dirname(dst)
        os.makedirs(parent_dir, exist_ok=True)
        shutil.copy(src, dst)

def unzip_file(zip_path, extract_path):
    cmd = f'unzip {zip_path} -d {extract_path}'
    print(cmd)
    os.system(cmd)


def zip_folder(folder_path, zip_path):
    with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, _, files in os.walk(folder_path):
            for file in files:
                file_path = os.path.join(root, file)
                arcname = os.path.relpath(file_path, start=folder_path)
                zipf.write(file_path, arcname)


def indexOf(s,t):
    return s.find(t)


def traversal_files(source_path, target_root, result_root):
    # 当前脚本文件路径
    dir_path = os.getcwd()

    for root, dirs, files in os.walk(source_path):
        for file in files:
            file_path = os.path.join(root, file)

            start = indexOf(file_path, dir_path)
            if start != -1:
                next_index = start + len(dir_path) + 1
                relative = f"{file_path[next_index:]}"
                # print(f"relative: {relative}")
                index = indexOf(relative, "/")
                target_file = target_root + relative[index:]
                result_file = result_root + relative[index:]

                target_path = os.path.join(dir_path, target_file)
                result_path = os.path.join(dir_path, result_file)
                
                # print(f"source_path: {file_path}")
                # print(f"target_path: {target_path}")
                # print(f"result_path: {result_path}")

                # 最新的这个class文件，在tag版本中也是存在的，保存起来
                if os.path.exists(target_path):
                    print(f"copy {file_path} -> {result_path}")
                    copy_file(file_path, result_path)
        


    

# 将当前代码与tag代码做比较，过滤出现存的tag代码
def main():
    script_path = sys.argv[0]
    # tag代码
    tag_code_zip = sys.argv[1]
    # 当前exec文件的代码
    new_code_zip = sys.argv[2]
    # 对比完之后的代码zip包
    code_zip = sys.argv[3]

    print(f"script_path: {script_path}")
    print(f"tag_code_zip: {tag_code_zip}")
    print(f"new_code_zip: {new_code_zip}")
    print(f"code_zip: {code_zip}")

    # 把zip包重新解压出来，后面做过滤
    dir_path = os.getcwd()
    tag_code_path = os.path.join(dir_path,f"{tag_code_zip[:-4]}")
    new_code_path = os.path.join(dir_path,f"{new_code_zip[:-4]}")
    code_path = os.path.join(dir_path,f"{code_zip[:-4]}")

    print(f"tag_code_path: {tag_code_path}")
    print(f"new_code_path: {new_code_path}")
    print(f"code_path: {code_path}")
    remove_folder(tag_code_path)
    remove_folder(new_code_path)
    remove_folder(code_path)

    code_zip_path = os.path.join(dir_path,f"{code_zip}")
    print(f"code_zip_path: {code_zip_path}")
    remove_file(code_zip_path)


    tag_code_zip_path = f"./{tag_code_zip}"
    new_code_zip_path = f"./{new_code_zip}"
    code_zip_path = f"./{code_zip}"
    unzip_file(tag_code_zip_path, tag_code_path)
    unzip_file(new_code_zip_path, new_code_path)

    # tag版本代码的目录
    split_path = tag_code_path.split("/")
    target_dir = split_path[len(split_path)-1]
    print(f"target_dir: {target_dir}")

    # 最终生成代码的目录
    split_path = code_path.split("/")
    result_dir = split_path[len(split_path)-1]
    print(f"result_dir: {result_dir}")

    
    traversal_files(new_code_path, target_dir, result_dir)

    # 把过滤出来的文件生成zip
    zip_folder(code_path,code_zip_path)

    return 0


# filter code base on tag
# -------------- main --------------
if __name__ == '__main__':
    sys_ret = 0
    try:
        sys_ret = main()
    except Exception as e:
        print(e)
        traceback.print_exc()
        sys_ret = 1
    finally:
        sys.exit(sys_ret)